package com.gjy.spring.util;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author gjy
 * @version 1.0
 * @since 2025-02-17 18:04:44
 */
public class TimeoutUtil {

    public static String timeout(Long sleep, Long s2, String msg) {
        ThreadPoolTaskExecutor executor = executor();

        Future<String> future = executor.submit(() -> {
            try {
                TimeUnit.SECONDS.sleep(s2);
                return "OK";
            } catch (Throwable e) {
                throw new RuntimeException(e);
            }
        });

        try {
            return future.get(sleep, TimeUnit.SECONDS);
        } catch (TimeoutException e) {
            future.cancel(true);
            return msg;
        } catch (Exception e) {
            return "内部错误";
        }
    }

    public static ThreadPoolTaskExecutor executor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(100);
        executor.setQueueCapacity(10);
        executor.setThreadFactory(
                new ThreadFactory() {
                    private final AtomicLong index = new AtomicLong(1);

                    @Override
                    public Thread newThread(Runnable r) {
                        return new Thread(r, "FileExecutor-task-pool-thread-" + index.getAndIncrement());
                    }
                }
        );
        executor.setRejectedExecutionHandler((r, executor1) -> {
            if (!executor1.isShutdown()) {
                try {
                    executor1.getQueue().put(r);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        executor.initialize();
        return executor;
    }

}
